Jak nejlepe udelat timeout urcite operace v threadu

Otázka od: Tomas Bradle

24. 8. 2004 23:50

Zdravim vsechny,

mam aplikaci, ktera zabezpecuje uzivatelsky interface k rizeni
technologickych operaci. Jadro rizeni je v samostatnem threadu, pres
synchronize se volaji odezvy do jiz zmineneho uzivatelskeho interface
(hlavni thread aplikace).

Ted bych potrebaval poradit, jak nejlepe udelat testovani timeoutu urcitych
bloku ridiciho kodu, napr.:

zacatek_timeoutu;
repeat
  ...
 until podminka or je_timeout

nebo jinak:

zacatek_timeoutu;
repeat
  ...
  if je_timeout then break;
  ...
 until podminka;

jde mi o to, jak nejlepe udelat mereni ubehnuteho casu, myslel jsem treba
pomoci GetTickCount, ale 47 dni se mi zda malo, kdyz jde o nepretrzity
provoz. Mate nekdo neco vyzouseneho ?

diky

Tomas Bradle
t.bradle@worldonline.cz



Odpovedá: Petr Fejfar

25. 8. 2004 8:12

Tomas Bradle wrote:

> treba pomoci GetTickCount, ale 47 dni se mi zda malo, kdyz jde o
> nepretrzity provoz.

Tak udelej to, co se pri odcitani bezne dela: vypujc si dalsi rad tj. 2^32.

A nebo to muzes nahradit:

- Now a TDateTime
- QueryPerformanceCounter (taky muze pretect)

Co pouzit zalezi na tom, jake mas na TO pozadavky.


HTH, pf


Odpovedá: delphin@post.cz

25. 8. 2004 10:03

> jde mi o to, jak nejlepe udelat mereni ubehnuteho casu, myslel jsem treba
> pomoci GetTickCount, ale 47 dni se mi zda malo, kdyz jde o nepretrzity
> provoz. Mate nekdo neco vyzouseneho ?

Tohle funguje s GetTickCount i kdyz dojde po 47 dnech k preteceni.

var TimeStamp:cardinal;

TimeStamp:=GetTickCount;
repeat
  ...
  if (GetTickCount-TimeStamp)>5000 then break;
  ...
 until podminka;



Now nelze pouzit, protoze cas jednak meni uzivatele, pak automaticka
synchronizace ve WinXP a take zmena letniho a zimniho casu.


Odpovedá: Petr Fejfar

25. 8. 2004 10:22

delphin@post.cz wrote:

> Tohle funguje s GetTickCount i kdyz dojde po 47 dnech k preteceni.
>
> var TimeStamp:cardinal;
>
> TimeStamp:=GetTickCount;
> repeat
> ...
> if (GetTickCount-TimeStamp)>5000 then break;
> ...
> until podminka;

Kdyz dojde k preteceni v ramci mereni periody tj. kdyz nastavis TimeStamp
pred pretecenim a vypocet GetTickCount-Timestamp vyhodnotis
po preteceni, tak to nefunguje. Musis udelat zaporny prenos.

pf


Odpovedá: Tomas Bradle

25. 8. 2004 11:07

Jo tohle presne jsem mel na mysli, takze vlastne staci zjistit jestli novy
TickCount je mensi nez ten, od ktereho se pocita a potom staci provest
korekci napr.:

korig_tc:=int64(GetTickCount)+high(DWORD)+1;

nebo se mylim ?

diky za pomoc

Tomas Bradle
t.bradle@worldonline.cz


----- Original Message -----
From: "Petr Fejfar" <development@callnet.cz>
To: <delphi-l@clexpert.cz>
Sent: Wednesday, August 25, 2004 11:22 AM
Subject: Re: Jak nejlepe udelat timeout urcite operace v threadu


> delphin@post.cz wrote:
>
> > Tohle funguje s GetTickCount i kdyz dojde po 47 dnech k preteceni.
> >
> > var TimeStamp:cardinal;
> >
> > TimeStamp:=GetTickCount;
> > repeat
> > ...
> > if (GetTickCount-TimeStamp)>5000 then break;
> > ...
> > until podminka;
>
> Kdyz dojde k preteceni v ramci mereni periody tj. kdyz nastavis TimeStamp
> pred pretecenim a vypocet GetTickCount-Timestamp vyhodnotis
> po preteceni, tak to nefunguje. Musis udelat zaporny prenos.
>
> pf
>
>
>
>
>



Odpovedá: delphin@post.cz

25. 8. 2004 11:10

> > Tohle funguje s GetTickCount i kdyz dojde po 47 dnech k preteceni.
> >
> > var TimeStamp:cardinal;
> >
> > TimeStamp:=GetTickCount;
> > repeat
> > ...
> > if (GetTickCount-TimeStamp)>5000 then break;
> > ...
> > until podminka;
>
> Kdyz dojde k preteceni v ramci mereni periody tj. kdyz nastavis TimeStamp
> pred pretecenim a vypocet GetTickCount-Timestamp vyhodnotis
> po preteceni, tak to nefunguje. Musis udelat zaporny prenos.

Jak presne to nefunguje ?
O tom, jestli to funguje nebo nefunguje se muzeme snadno presvedcit:

var TimeStamp,TickCount,Result:cardinal;
begin
 TimeStamp:=$FFFFFFFF;
 TickCount:=$00000000;
 Result:=TickCount-TimeStamp;

TickCount TimeStamp Result
$00000000-$FFFFFFFF=$00000001
$00000001-$FFFFFFFF=$00000002
$00000001-$FFFFFFFE=$00000003
$00000002-$FFFFFFFE=$00000004
$00000002-$FFFFFFFD=$00000005

atd ...


Odpovedá: Petr Fejfar

25. 8. 2004 12:54

delphin@post.cz wrote:

> Jak presne to nefunguje ?
> O tom, jestli to funguje nebo nefunguje se muzeme snadno presvedcit:

Clovece mas pravdu - ono to vskutku funguje - Delphi u typu DWORD/CARDINAL
z nejakeho duvodu netestuje preteceni, takze nedojde k Range Check Error,
zatimco u typu WORD a BYTE ano. To jsou veci....

pf



Odpovedá: delphin@post.cz

25. 8. 2004 13:03

> Clovece mas pravdu - ono to vskutku funguje - Delphi u typu DWORD/CARDINAL
> z nejakeho duvodu netestuje preteceni, takze nedojde k Range Check Error,
> zatimco u typu WORD a BYTE ano. To jsou veci....

To se da zapnout/vypnout {$Q+-}a {$R+-}


Odpovedá: Petr Fejfar

25. 8. 2004 14:43

delphin@post.cz wrote:
>> Clovece mas pravdu - ono to vskutku funguje - Delphi u typu
>> DWORD/CARDINAL z nejakeho duvodu netestuje preteceni, takze nedojde
>> k Range Check Error, zatimco u typu WORD a BYTE ano. To jsou veci....
>
> To se da zapnout/vypnout {$Q+-}a {$R+-}

Asi jak komu a jak kdy  

- alespon me D6.02prof bere u direktivy $Q posledni hodnotu
v unit, prestoze je v helpu popisovana se scope local,
takze tu direktivu nepouzivame. napr.

...
{$Q-}
 Vypocet A; // Vyvola EIntOverflow !!!
{$Q+}
Vypocet B;

a naopak

{$Q+}
 Vypocet A; // Nevyvola EIntOverflow !!!
{$Q-}

***

A zapnuti $R+ rozsah u dword nekontroluje vubec (k memu prekvapeni)
- zrejme si rekli, ze co je v registru EAX, to se taky vejde do pameti
a v zasade maji pravdu  


pf